/**
 * 辅助jstree实现定位
 * @author wugang5@ygsoft.com
 * @date 2016/10/27 17:13:52
 */
define(["jquery","ecp.utils.i18n","ecp.const"], function ($, locale,Const) {
    //定位模板
    var HTML = '<div class="search-input-dingwei" style="width:{width}">' +
        '<i class="iconSearch"></i>' +
        '<input type="text" required class="form-control" placeholder="{placeholder}">' +
        '<i class="btnClear" title="清空" ng-title="locale.clearAll" style="display: none;"></i>' +
        '<span class="textNumber"></span>' +
        '<button class="btnUp"></button>' +
        '<button class="btnDown"></button>' +
        '</div>';
    //语言包
    var _locale = locale.search;
    /**
     * 构造函数
     * @param options
     * @constructor
     */
    var Plugin = function (options) {
        this.init(options);
        this.render();
        this.bindEvent();
    };
    Plugin.prototype = {
        /**
         * 初始化
         * @param options
         */
        init: function (options) {
            this.options = $.extend({}, this.getDefaultOpts(), options || {});
            this.$container = $(this.options.container);
            this.$jstree = $(this.options.jstreeObject);
            //没有配置container或jstreeObject终止
            if (!this.$container.length || !this.$jstree.length) {
                console && console.error("required container and jstreeObject.");
                return;
            }
            //jstree必须配置serach插件
            if(this.$jstree.jstree && this.$jstree.jstree(true) && typeof (this.$jstree.jstree(true).search) !== 'function'){
                console && console.error("jstree must config search plugin.");
                return;
            }
            this.HTML = HTML.replace(/{width}/g, this.options.width).replace(/{placeholder}/g, this.options.placeholder);
        },
        /**
         * 渲染
         */
        render: function () {
            //生成模板
            this.$container.html(this.HTML);
            //国际化
            $.replaceI18nAttr(_locale, this.$container, "title");
            this.setJqElement();
        },
        /**
         * 事件绑定
         */
        bindEvent: function () {
            this.bindClearBtn();
            this.bindInput();
            this.bindBtnUp();
            this.bindBtnDown();
        },
        /**
         * 清除按钮事件
         */
        bindClearBtn: function () {
            var that = this;
            that.$btnClear.off('click').on('click', function () {
                that.$searchInput.val("").focus();
                that.$btnClear.fadeOut("fast").hide();
                that.$iconSearch.fadeIn("fast").show();
                //执行搜索
                that.excuteSearch();
            });
        },
        /**
         * 输入框事件
         */
        bindInput: function () {
            var isEnterKey = false,
                that = this;
            that.$searchInput.off('keyup').on('keyup', function (event) {
                var e = event || window.event, 
                    $this = $(this),
                    searchVal = $this.val();
				//F1216026 阻止冒泡 modi zxw
				e.stopPropagation();
                if (searchVal !== '') {
                    that.$btnClear.fadeIn("fast").show();
                } else {
                    that.$iconSearch.fadeIn("fast").show();
                }
                isEnterKey = false;
                //键盘enter
                if (e.keyCode == 13) {
                    isEnterKey = true;
                    var newValue = that.getSearchVal();
                    if (that.oldValue !== newValue) {
                        that.oldValue = newValue;
                        that.excuteSearch();
                    } else {
                        //相同的搜索值触发下定位到下一个
                        that.$btnDown.trigger("click");
                    }
                } else {
                    //连续输入清除定时器
                    if (this.timeoutID) {
                        clearTimeout(this.timeoutID);
                    }
                    this.timeoutID = setTimeout(function () {
                        if (!isEnterKey) {
                            that.excuteSearch();
                        }
                    }, 300);
                }
            });
            that.$searchInput.on('focus', function () {
                that.$btnUp.addClass("active");
                that.$btnDown.addClass("active");
            });
            that.$searchInput.on('blur', function () {
                if (that.$searchInput.val() == '') {
                    that.$btnUp.removeClass("active");
                    that.$btnDown.removeClass("active");
                }
            });
        },
        /**
         * 绑定向上按钮事件
         */
        bindBtnUp: function () {
            var that = this;
            that.$btnUp.on('click', function () {
                var list = that.getMatchResult(),
                    len = list.length;
                if (len > 1) {
                    var $active = that.getActive(),
                        activeIndex = that.getActiveIndex(list);
                    if ($active && $active.length) {
                        var $prev = $(list[--activeIndex], that.$jstree);
                        if($prev.length){
                            that.showTextNumber(activeIndex + 1, len);
                        } else {
                            that.showTextNumber(len, len);
                            //最后一个
                            $prev = $(list[list.length - 1], that.$jstree);
                        }
                        $prev.addClass("active");
                        $active.removeClass("active");
                        //出现滚动条时可能需要滚动到可视区域
//                        if(that.$jstree[0].scrollHeight > that.$jstree.height()){
                            that.scroll($prev);
//                        }
                    }
                }
            });
        },
        /**
         * 绑定向下按钮事件
         */
        bindBtnDown: function () {
            var that = this;
            that.$btnDown.on('click', function () {
                var list = that.getMatchResult(),
                    len = list.length;
                if (len > 1) {
                    var $active = that.getActive(),
                        activeIndex = that.getActiveIndex(list);
                    if ($active && $active.length) {
                        var $next = $(list[++activeIndex], that.$jstree);
                        if($next.length){
                             that.showTextNumber(activeIndex + 1, len);
                        } else {
                            that.showTextNumber(1, len);
                            //指向第一个
                            $next = $(list[0], that.$jstree);
                        }
                        $next.addClass("active");
                        $active.removeClass("active");
                        //出现滚动条时可能需要滚动到可视区域
//                        if(that.$jstree[0].scrollHeight > that.$jstree.height()){
                            that.scroll($next);
//                        }
                    }
                }
            });
        },
        /**
         * 执行搜索
         */
        excuteSearch: function () {
            //先清除之前的搜索样式
            this.removeClass();
            this.$jstree.jstree(true).search(this.getSearchVal());
            //执行回调 
            (typeof this.options.callback === 'function') && this.options.callback.call(null, this.getSearchVal());
            //重置被关键字匹配的样式
            this.resetClass();
            var list = this.getMatchResult(),
                activeIndex = this.getActiveIndex(list);
            if (list.length) {
                //显示当前位置
                this.showTextNumber(activeIndex + 1, list.length);
            } else {
                this.showTextNumber(0, 0);
            }
        },
        /**
         * 设置属性
         */
        setJqElement: function () {
            this.$iconSearch = $(".iconSearch", this.$container);
            this.$searchInput = $("input[type='text']", this.$container);
            this.$btnClear = $(".btnClear", this.$container);
            this.$textNumber = $(".textNumber", this.$container);
            this.$btnUp = $(".btnUp", this.$container);
            this.$btnDown = $(".btnDown", this.$container);
        },
        /**
         * 获取默认配置
         * @returns {{width: string, placeholder: *, callback: Function, jstreeObject: string}}
         */
        getDefaultOpts: function () {
            return {
                width: "300px",
                placeholder: _locale.placeholder,
                callback: function () {
                },
                jstreeObject: ''
            };
        },
        /**
         * 重置匹配结果的样式
         */
        resetClass: function () {
            var list = this.getMatchResult();
            if (list && list.length) {
                list.each(function () {
                    $(this).removeClass("jstree-search").addClass("dwCheck");
                });
                //设置第一个为激活状态
                $(list[0], this.$jstree).addClass("active");
                this.scroll(list[0]);
            }
        },
        /**
         * 获取输入框的值
         * @returns {*}
         */
        getSearchVal: function () {
            return this.$searchInput.val();
        },
        /**
         * 获取匹配结果
         * @returns {*}
         */
        getMatchResult: function () {
            var $jstree = this.$jstree,
                list = null;
            if ($jstree && $jstree.length === 1) {
                list = $jstree.find("a[class*='jstree-search']");
                if (list.length === 0) {
                    list = $jstree.find("a[class*='dwCheck']")
                }
                return list;
            } else {
                return [];
            }
        },
        /**
         * 获取激活的元素
         * @returns {Mongo.Cursor|any}
         */
        getActive: function () {
        	//jstree选中时find("a[class*='dwCheck active']")失效
        	var ret = this.$jstree.find("a[class*='dwCheck active']");
        	if(ret.length === 0){
        		ret = this.$jstree.find("a[class*='active']")
        	}
        	return ret;
        },
        /**
         * 获取当前激活的元素在总列表的索引位置
         * @param list
         * @returns {number}
         */
        getActiveIndex: function (list) {
            var index = 0,
                that = this,
                $jstree = this.$jstree;
            $.each(list, function (i, n) {
                if ($(n, $jstree).hasClass("active")) {
                    index = i;
                    return false;
                }
            })
            return index;
        },
        /**
         * 显示当前定位位置
         * @param current
         * @param account
         */
        showTextNumber: function (current, account) {
            this.$textNumber.text(current + "/" + account)
        },
        /**
         * 删除dwCheck样式
         */
        removeClass: function(){
            var that = this,
                $list = that.$jstree.find(".dwCheck"),
                $current;
            $.each($list, function(i, e){
                $current = $(e, that.$jstree);
                $current.removeClass("dwCheck");
                if($current.hasClass("active")){
                    $current.removeClass("active");
                }
            });
        },
        /**
         * 滚动到可视区域
         * 通常滚动父容器
         */
        scroll: function(nextNode){
        	var me = this,
        		container = me.$jstree,//容器
        		pHeight = container.height(),
        		pScrolltop = container.scrollTop(),
        		pTop = container.offset().top,
        		nnHeight = $(nextNode).height(),
        		nnTop = $(nextNode).offset().top;
        	//如果下个节点在当前可视区域则不处理
        	if((nnHeight+nnTop > pTop) && (nnHeight+nnTop < pTop + pHeight )){
        		return;
        	}
        	//处理下个节点在当前可视区域下方
        	var offTop = (nnTop + nnHeight)-(pTop + pHeight);
        	//F1218937 解决定位滚动条移动位置
        	if(offTop>0){
        		//判断是否存在横向滚动条，如果存在则增加滚动条高度
        		var scrollSize=0;
        		if(container[0].offsetHeight > container[0].clientHeight){
        			scrollSize = Const.ScrollBarSize;
        		}
        		container.scrollTop(offTop + pScrolltop + scrollSize);
        	}else if(nnTop + nnHeight <= pTop){
        		//处理下个节点在当前可视区域上方
        		container.scrollTop(pScrolltop - (pTop - nnTop + nnHeight) );
        	}
        }
    };
    return {
        /**
         * 渲染入口
         * @param options
         * @returns {Plugin}
         */
        render: function (options) {
            var plugin = new Plugin(options);
            return plugin;
        }
    }
});